<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="embroot.css">
<TITLE>
Attachment
</TITLE>
</HEAD>
<BODY >
<A HREF="embroot054.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="embroot052.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="embroot056.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc108">10.3</A>&nbsp;&nbsp;Attachment</H2><UL>
<LI><A HREF="embroot055.html#toc58">An example</A>
</UL>

<A NAME="remoteattach"></A>
<BLOCKQUOTE CLASS="figure"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
<DIV CLASS="center">
<IMG SRC="embroot005.gif">
</DIV>
<BR>
<BR>
<DIV CLASS="center">Figure 10.1: Summary of the attachment protocol</DIV><BR>
<BR>

<A NAME="rattach"></A>
<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>
The attachment process is summarised in Figure&nbsp;<A HREF="#remoteattach">10.3</A>. It is
initiated from the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, by either calling
<A HREF="../bips/kernel/externals/remote_connect-3.html"><B>remote_connect/3</B></A><A NAME="@default321"></A> or the more flexible <A HREF="../bips/kernel/externals/remote_connect_setup-3.html"><B>remote_connect_setup/3</B></A><A NAME="@default322"></A>
and <A HREF="../bips/kernel/externals/remote_connect_accept-6.html"><B>remote_connect_accept/6</B></A><A NAME="@default323"></A> pair. In fact, <B>remote_connect/3</B> is implemented using <B>remote_connect_setup/3</B> and <B>remote_connect_accept/6</B> with default
values for some of the arguments. <BR>
<BR>
The attachment can be divided into several phases: 
<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
Initialisation and handshaking: the control connection is
established, and handshaking between the two sides are carried out &ndash;
checking that the remote protocols on the two sides are compatible;
checking the pass-term.
<LI CLASS="li-enumerate">Establishing the ERPC connections and exchange of information
(remote language, ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> name for the peer).
<LI CLASS="li-enumerate">User-defined initialisations.
</OL>
The remote protocol version is stored in the flag <TT>remote_protocol_version</TT>, accessible via <A HREF="../bips/kernel/env/get_flag-2.html"><B>get_flag/2</B></A><A NAME="@default324"></A>
as an integer version number.
This version number should only change when the protocol is
modified. Checking of the version ensures that the same (or at
least compatible) versions of the protocol are used, so that the two sides
behaves correctly. The version information is sent from the remote side
(which must have its own copy of the version information), and the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side checks that this is compatible with the protocol version it
is using. In order to cope with remote connections which may not be using
the remote protocol, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side waits only for a fixed period of
time for the remote side to send the version information before timing out.<BR>
<BR>
Time-out on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side can also occur for forming any of the
connections between the two sides, from the control connection to the peer
queue. This is specified by the user in <TT>remote_connect_accept/6</TT>. If
time-out occurs during the attachment, then the attachment process is
abandoned, and the predicate fails (any connected sockets will be closed).<BR>
<BR>
The detailed sequence of events for the attachment for the remote side
(with some description of the relevant ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side actions) are:
<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side: a socket server for the control connection is
created, using the address Host/Port which can be specified by the
user. It then waits to accept a socket stream for the control connection
from the remote side. The user can specify the amount of time to wait
before this operation times-out, which would then terminate the attachment.<BR>
<BR>
<LI CLASS="li-enumerate">Remote side: create a client socket stream for the control connection,
with an address compatible with Host/Port. The socket stream should
be in blocking mode, and perform no translation on the data sent.
<LI CLASS="li-enumerate">Remote side: sends the remote protocol version information on the
control socket in EXDR format and flush it. This should be a <TT>remote_protocol/1</TT> term. 
<LI CLASS="li-enumerate">ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side: reads the EXDR version term from the control
socket, and compares with the version on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. If the two
protocols are compatible, it sends the EXDR string <TT>yes</TT> back to
the remote side; otherwise it sends the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> remote protocol version
to the remote side and disconnects from the remote side (raising
unimplemented functionality error). The ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side waits at
most 100 seconds after the control connection is established for the remote side's version: after
this the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side disconnects the control connection and raises out
of range error. 
<LI CLASS="li-enumerate">It is expected that the future versions of the protocol will remain
unchanged up to this point at least, to ensure the proper handshaking and
checking of versions.
<LI CLASS="li-enumerate">Remote side: write the `pass-term' in EXDR format on the newly created control
connection and flush it. This provides a simple security check: ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side will check if the `pass-term' matches the `pass-term' it was given
when the remote connection was initiated &ndash; for <A HREF="../bips/kernel/externals/remote_connect-3.html"><B>remote_connect/3</B></A><A NAME="@default325"></A>, the
pass-term is the empty string, but the user can specify any pass-term if
<A HREF="../bips/kernel/externals/remote_connect_setup-3.html"><B>remote_connect_setup/3</B></A><A NAME="@default326"></A> and <A HREF="../bips/kernel/externals/remote_connect_accept-6.html"><B>remote_connect_accept/6</B></A><A NAME="@default327"></A> are
used. If the terms are not identical, then the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side will
discontinue the attachment process.<BR>
<BR>
<LI CLASS="li-enumerate">Remote side: read from the control connection the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> name for the control
connection. This is sent in EXDR format, and is used to identify this
particular remote attachment &ndash; the peer name for the peer. This name is needed when calling ec_rpc goals
that refer to the peer. 
<LI CLASS="li-enumerate">Remote side: write the name of the programming language (e.g. tcl, java) of the
remote process on the control connection. This should be in EXDR string
format, and the connection flushed. 
<LI CLASS="li-enumerate">ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side: read the name of the programming language and store
it (it can be accessed later via <A HREF="../bips/kernel/externals/peer_get_property-3.html"><B>peer_get_property/3</B></A><A NAME="@default328"></A>). The ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side now wait to accept the socket stream (using the same socket server as
the control connection) for the ec_rpc connection. This can also time-out.
<LI CLASS="li-enumerate">Remote side: create a client socket stream for the ec_rpc connection, using the
same Port as for the control connection. This stream should be in
blocking mode, and perform no translation on the data sent. The server
socket on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> will be closed after accepting this client.
<LI CLASS="li-enumerate">Remote side: read the control connection name again on the remote side, on the
newly established ec_rpc connection. This is also sent in EXDR format. This
is designed to verify that the ec_rpc connection is indeed connected to the
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side. 
<LI CLASS="li-enumerate">Remote side: the remote side now has control. Any user-defined initialisations on the remote
side can now be performed, to make the remote side ready for the
interaction. The remote side has the control initially. Note that
user-defined initialisations on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side is also performed after
sending the control name on the ec_rpc connection. After the
initialisation, ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side will suspend and listen on the control
connection for the remote side to give control back to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side.
</OL>
At the end of this, the remote side should be ready for normal interaction
with the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side.<BR>
<BR>
The remote_connect/3 or remote_connect_accept/6 predicate wait for the control to be handed back by
the remote side before exiting. Thus when the predicate succeeds, the
remote side has been attached and properly initialised, with ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side having control.<BR>
<BR>
The protocol does not specify how the remote side should be informed of the
Host/Port address for the initial socket connection. The Address can be
fixed before hand (with the Address argument instantiated, or
the information can be transmitted either manually or via files. In
addition, the remote process can be started from within ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> using
the <A HREF="../bips/kernel/opsys/exec-3.html"><B>exec/3</B></A><A NAME="@default329"></A> command, with the host and port supplied as arguments.<BR>
<BR>
In accepting client socket connections from the remote side, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side is informed of the host of the remote side. This should either be the
client's hostname, or 'localhost'. After accepting the control connection,
subsequent connections (for ec_rpc and any peer queues) are checked to
ensure that they are from the same client. If not, the attachment is
terminated by ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>. Using 'localhost' as the name on either side will
restrict the two sides to be on the same machine (and they must both use
localhost for Host in the address, rather than the actual hostname). <BR>
<BR>
<A NAME="toc58"></A>
<H3 CLASS="subsection"><A NAME="htoc109">10.3.1</A>&nbsp;&nbsp;An example</H3>
The following is a simple example of making a remote attachment on the
remote side. In this case, the remote side is also an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> program.
A remote attachment by a program written in another programming language
will need to provide a similar function in that language:
<PRE CLASS="verbatim">
% Example code for making a remote attachment on the remote side

:- local variable(ecsidehost).

% remote_attach/6 makes a remote attachment to a host ECLiPSe program.
% Args:
%    +Host: host name on ECLiPSe side
%    +Port: port on ECLiPSe side
%    +Pass: `pass-term' - used to verify the connection
%    +Init: goal to call to perform any application specific initialisation
%    -Control: the remote side (local) name of the control connection
%    -Ec_rpc:  the remote side name of the ec_rpc connection
%    -EcSideControl: the ECLiPSe side name for the control connection

remote_attach(Host, Port, Pass, Init, Control, Ec_rpc, EcSideControl) :-
     % control connection
     new_client_socket(Host, Port, Control),
     % send the protocol version information to the ECLiPSe side
     % we are the remote side, so must have our own version info.
     write_exdr(Control, remote_protocol(1)), flush(Control),
     % read response from ECLiPSe side to make sure it is compatible...
     read_exdr(Control, IsSameVersion),
     (IsSameVersion == "yes" -&gt;
         true 
     ; 
         writeln("Incompatible versions of remote protocol. Failing...."),
         fail
     ),
     % send pass-term; if this does not match the pass-term on the ECLiPSe
     % side, it will terminate the attachment
     write_exdr(Control, Pass), flush(Control),
     % ECLiPSe side name for connection
     read_exdr(Control, EcSideControl),
     % send language name to ECLiPSe side
     write_exdr(Control, "eclipse"), flush(Control),
     % Ec_rpc connection
     new_client_socket(Host, Port, Ec_rpc),
     % read control name again on Ec_rpc to verify connection
     % in a more sophisticated implementation, this should time-out
     (read_exdr(Ec_rpc, EcSideControl) -&gt;
        true 
     ; 
 % if not verified, terminate connection
        close(Control), close(Ec_rpc),
        fail
     ),
     % Remote side now has control, call Init to perform application
     % specific initialisations
     call(Init),
     % hand control over to ECLiPSe side...
     write_exdr(Control, resume), flush(Control).


new_client_socket(Host, Port, Socket) :-
     socket(internet, stream, Socket),
     connect(Socket, Host/Port).

%----------------------------------------------------
% the following code make use of remote_attach/6 to make an attachment,
% and then disconnect immediately when ECLiPSe side returns control

test(Host, Port) :-
     % make the remote attachment. For this simple example, there is no
     % application specific initialisations, and the default pass-term
     % of an empty string is used...
     remote_attach(Host, Port, "", true, Control, Ec_rpc, _),
     % control has been given to ECLiPSe side, wait for ECLiPSe side to
     % return control....
     read_exdr(Control, _),
     % immediately disconnect from ECLiPSe side
     write_exdr(Control, disconnect), flush(Control),
     % wait for ECLiPSe side to acknowledge disconnect...
     read_exdr(Control, disconnect_yield),
     % clean up
     close(Control), close(Ec_rpc).

</PRE>
In addition to the attachment, the example contains a very simple example
of using the protocol by exchanging control messages with the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side. After attachment, it disconnects the remote attachment as soon as
control is handed back to it. For more details on the messages, see next
section. <BR>
<BR>
To try out the example, start an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> session and initiate a remote
attachment. This process is the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side:
<PRE CLASS="verbatim">
(ECLiPSe side)
[eclipse 1]: remote_connect(Host/Port, Control, _).
Socket created at address chicken.icparc.ic.ac.uk/32436
</PRE>
Now start another ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> session, compile the example program, and make
the attachment to the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side:
<PRE CLASS="verbatim">
(Remote side)
[eclipse 4]: test('chicken.icparc.ic.ac.uk', 32436).
</PRE>
On the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side, <TT>remote_connect/3</TT> should now succeed:
<PRE CLASS="verbatim">
(ECLiPSe side)
Host = 'chicken.icparc.ic.ac.uk'
Port = 32436
Control = peer3
yes.
[eclipse 2]: 
</PRE>
The remote side is suspended, awaiting the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side to return
control. To return control to the remote side, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> side should
call <A HREF="../bips/kernel/externals/remote_yield-1.html"><B>remote_yield/1</B></A><A NAME="@default330"></A> (see section&nbsp;<A HREF="embroot058.html#remotesupport">10.6</A> for a description
of <TT>remote_yield/1</TT>):
<PRE CLASS="verbatim">
(ECLiPSe side)
[eclipse 2]: remote_yield(peer3).
Abort
[eclipse 3]:
</PRE>
In this simple example, when control is returned to remote side, it
immediately disconnects, thus the <TT>remote_yield/1</TT> on the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>
side is aborted (as disconnect was initiated from the remote side), as per
the disconnect protocol.
<PRE CLASS="verbatim">
(Remote side)
[eclipse 4]: test('chicken.icparc.ic.ac.uk', 32436).

yes.
[eclipse 5]: 
</PRE>
<HR>
<A HREF="embroot054.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="embroot052.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="embroot056.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
